package com.fy.market.trigger.http;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.fy.market.types.common.reslut.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 模拟登录认证控制器
 * 提供登录、登出、权限校验等模拟功能
 *
 * @author fy
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
@Tag(name = "认证管理", description = "用户登录认证、权限管理相关接口")
public class AuthController {

    /**
     * 模拟用户登录
     * 用户名: admin, 密码: 123456 -> 管理员角色
     * 用户名: user, 密码: 123456 -> 普通用户角色
     * 用户名: guest, 密码: 123456 -> 访客角色
     */
    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "模拟用户登录，支持admin/user/guest三种角色")
    public R<Map<String, Object>> login(@RequestParam String username, @RequestParam String password) {
        log.info("用户登录请求: username={}", username);
        
        // 模拟用户验证
        if (!"123456".equals(password)) {
            return R.no("密码错误");
        }
        
        Map<String, Object> userInfo = new HashMap<>();
        String role;
        String[] permissions;
        
        switch (username) {
            case "admin":
                role = "admin";
                permissions = new String[]{"user:add", "user:delete", "user:update", "user:query", "system:config"};
                userInfo.put("userId", 1L);
                userInfo.put("username", "admin");
                userInfo.put("nickname", "系统管理员");
                userInfo.put("role", role);
                userInfo.put("permissions", permissions);
                break;
            case "user":
                role = "user";
                permissions = new String[]{"user:query", "user:update"};
                userInfo.put("userId", 2L);
                userInfo.put("username", "user");
                userInfo.put("nickname", "普通用户");
                userInfo.put("role", role);
                userInfo.put("permissions", permissions);
                break;
            case "guest":
                role = "guest";
                permissions = new String[]{"user:query"};
                userInfo.put("userId", 3L);
                userInfo.put("username", "guest");
                userInfo.put("nickname", "访客用户");
                userInfo.put("role", role);
                userInfo.put("permissions", permissions);
                break;
            default:
                return R.no("用户不存在");
        }
        
        // 执行登录
        StpUtil.login(userInfo.get("userId"));
        
        // 设置用户角色和权限
        StpUtil.getSession().set("userInfo", userInfo);
        StpUtil.getRoleList().clear();
        StpUtil.getRoleList().add(role);
        StpUtil.getPermissionList().clear();
        for (String permission : permissions) {
            StpUtil.getPermissionList().add(permission);
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("token", StpUtil.getTokenValue());
        result.put("userInfo", userInfo);
        result.put("loginTime", System.currentTimeMillis());
        
        log.info("用户登录成功: userId={}, role={}", userInfo.get("userId"), role);
        return R.ok(result);
    }

    /**
     * 用户登出
     */
    @PostMapping("/logout")
    @Operation(summary = "用户登出", description = "用户登出，清除登录状态")
    @SaCheckLogin
    public R<String> logout() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("用户登出: userId={}", userId);
        
        StpUtil.logout();
        return R.ok("登出成功");
    }

    /**
     * 获取当前用户信息
     */
    @GetMapping("/userInfo")
    @Operation(summary = "获取用户信息", description = "获取当前登录用户的信息")
    @SaCheckLogin
    public R<Map<String, Object>> getUserInfo() {
        Long userId = StpUtil.getLoginIdAsLong();
        Map<String, Object> userInfo = (Map<String, Object>) StpUtil.getSession().get("userInfo");
        
        Map<String, Object> result = new HashMap<>();
        result.put("userId", userId);
        result.put("userInfo", userInfo);
        result.put("roles", StpUtil.getRoleList());
        result.put("permissions", StpUtil.getPermissionList());
        result.put("loginTime", System.currentTimeMillis());
        
        return R.ok(result);
    }

    /**
     * 模拟删除用户操作 - 需要管理员权限
     */
    @DeleteMapping("/user/{userId}")
    @Operation(summary = "删除用户", description = "删除指定用户，需要管理员权限")
    @SaCheckLogin
    @SaCheckRole("admin")
    @SaCheckPermission("user:delete")
    public R<String> deleteUser(@PathVariable Long userId) {
        log.info("管理员删除用户: operatorId={}, targetUserId={}", StpUtil.getLoginIdAsLong(), userId);
        
        // 模拟删除操作
        if (userId == 1L) {
            return R.no("不能删除超级管理员");
        }
        
        // 这里应该是实际的删除逻辑
        log.info("模拟删除用户成功: userId={}", userId);
        return R.ok("删除用户成功");
    }

    /**
     * 模拟更新用户信息 - 需要用户权限
     */
    @PutMapping("/user/{userId}")
    @Operation(summary = "更新用户信息", description = "更新用户信息，需要用户权限")
    @SaCheckLogin
    @SaCheckPermission("user:update")
    public R<String> updateUser(@PathVariable Long userId, @RequestParam String nickname) {
        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("更新用户信息: operatorId={}, targetUserId={}, nickname={}", currentUserId, userId, nickname);
        
        // 模拟权限检查：普通用户只能更新自己的信息
        if (StpUtil.hasRole("user") && !currentUserId.equals(userId)) {
            return R.no("权限不足，只能更新自己的信息");
        }
        
        // 这里应该是实际的更新逻辑
        log.info("模拟更新用户信息成功: userId={}, nickname={}", userId, nickname);
        return R.ok("更新用户信息成功");
    }

    /**
     * 模拟查询用户列表 - 需要查询权限
     */
    @GetMapping("/users")
    @Operation(summary = "查询用户列表", description = "查询用户列表，需要查询权限")
    @SaCheckLogin
    @SaCheckPermission("user:query")
    public R<Map<String, Object>> getUserList(@RequestParam(defaultValue = "1") int page, 
                                             @RequestParam(defaultValue = "10") int size) {
        log.info("查询用户列表: operatorId={}, page={}, size={}", StpUtil.getLoginIdAsLong(), page, size);
        
        // 模拟查询结果
        Map<String, Object> result = new HashMap<>();
        result.put("page", page);
        result.put("size", size);
        result.put("total", 3);
        // 创建用户列表
        Map<String, Object> adminUser = new HashMap<>();
        adminUser.put("userId", 1L);
        adminUser.put("username", "admin");
        adminUser.put("nickname", "系统管理员");
        adminUser.put("role", "admin");
        
        Map<String, Object> normalUser = new HashMap<>();
        normalUser.put("userId", 2L);
        normalUser.put("username", "user");
        normalUser.put("nickname", "普通用户");
        normalUser.put("role", "user");
        
        Map<String, Object> guestUser = new HashMap<>();
        guestUser.put("userId", 3L);
        guestUser.put("username", "guest");
        guestUser.put("nickname", "访客用户");
        guestUser.put("role", "guest");
        
        result.put("users", new Object[]{adminUser, normalUser, guestUser});
        
        return R.ok(result);
    }

    /**
     * 模拟系统配置操作 - 需要系统配置权限
     */
    @PostMapping("/system/config")
    @Operation(summary = "系统配置", description = "系统配置操作，需要系统配置权限")
    @SaCheckLogin
    @SaCheckPermission("system:config")
    public R<String> systemConfig(@RequestParam String configKey, @RequestParam String configValue) {
        log.info("系统配置操作: operatorId={}, key={}, value={}", StpUtil.getLoginIdAsLong(), configKey, configValue);
        
        // 这里应该是实际的配置逻辑
        log.info("模拟系统配置成功: key={}, value={}", configKey, configValue);
        return R.ok("系统配置成功");
    }

    /**
     * 检查登录状态
     */
    @GetMapping("/check")
    @Operation(summary = "检查登录状态", description = "检查当前用户是否已登录")
    public R<Map<String, Object>> checkLogin() {
        boolean isLogin = StpUtil.isLogin();
        Map<String, Object> result = new HashMap<>();
        result.put("isLogin", isLogin);
        
        if (isLogin) {
            result.put("userId", StpUtil.getLoginIdAsLong());
            result.put("tokenValue", StpUtil.getTokenValue());
            result.put("loginTime", System.currentTimeMillis());
        }
        
        return R.ok(result);
    }

    /**
     * 获取权限列表
     */
    @GetMapping("/permissions")
    @Operation(summary = "获取权限列表", description = "获取当前用户的权限列表")
    @SaCheckLogin
    public R<Map<String, Object>> getPermissions() {
        Map<String, Object> result = new HashMap<>();
        result.put("roles", StpUtil.getRoleList());
        result.put("permissions", StpUtil.getPermissionList());
        result.put("userId", StpUtil.getLoginIdAsLong());
        
        return R.ok(result);
    }
}